/***********************************************************************
    Written By Alex "SparkyMcSparks" Romo
    
    Questions? Concerns? Suggestions?
        Contact Me On AIM @ DareDevilSparks7
***********************************************************************/

/****************************************************************************
    Common Utilities
****************************************************************************/

/*
Borrowed From Max's Original Game Script
*/
function getEnt( className )

    local entities = { }
    local startEntity = nil
    
    repeat
    
        startEntity = Shared.FindEntityWithClassname(className, startEntity)    
        
        if (startEntity ~= nil) then
            table.insert(entities, startEntity)
        end
    
    until (startEntity == nil)
    
    return entities

end

/*
Returns The Distance Between Two Origins
*/
function distance( org, org2 )
    local distance = 0
    
    distance = org - org2
    
    if( distance < 0 ) then
        distance = distance * -1
    end
    
    return distance
end

/*
Basic Timer Wait
    -- Don't Use, Eats Up CPU.
*/
function wait( time )
    local currentTime = Shared.GetTime()
    local waitTime = currentTime + time
    
    while( waitTime >= Shared.GetTime() ) do
        // Waiting
    end
    
    return true
end

/*
Waits For Player To Be In Range
*/
function waittillPlayerInRange( org, range )
    while ( true ) do
        if( distance( org, Client.GetLocalPlayer():GetOrigin() ) <= range ) then
            break
        // Waiting
        end
    end
    
    return true
end

/*
Returns The Closest Entity In Array
*/
function getClosest( org, arr, max )
    if( max == nil ) then
        max = 999999
    end

    local newDist = 0
    local index = nil
	local ent = nil
	
	for index = 1, table.maxn( arr ) do
		newDist = distance( arr[ index ]:getOrigin(), org )
		if ( newDist >= max ) then
			// Nothing
		else
		    max = newDist
		    ent = arr[ index ]
		end
	end
	
	return ent
end

/*
Returns The Farthest Entity In Array
*/
function getFarthest( org, arr, max )
    if( max == nil ) then
        max = 999999
    end
	
	local dist = 0
	local newDist = 0
	local index = nil
	local ent = nil
	
    for index = 1, table.maxn( arr ) do
		newDist = distance( arr[ index ]:getOrigin(), org )
		if ( newDist <= dist or newDist >= max ) then
		    // Nothing
		else
		    dist = newDist
		    ent = arr[ index ]
		end
	end
	
	return ent
end

/*
Returns All Entities In Array Within Range
*/
function getWithinRange( org, arr, dist )
    local index = nil
    local ents = { }
    
	for index = 1, table.maxn( arr ) do
		if ( distance( arr[ index ]:getOrigin(), org ) <= dist ) then
			ents[ table.maxn( ents ) ] = arr[ index ]
	    end
	end
	
	return ents
end

/*
Returns All Entities In Array Outside Range
*/
function getOutsideRange( org, arr, dist )
    local index = nil
    local ents = { }
    
	for index = 1, table.maxn( arr ) do
		if ( distance( arr[ index ]:getOrigin(), org ) > dist ) then
			ents[ table.maxn( ents ) ] = arr[ index ]
	    end
	end
	
	return ents
end

/*
Adds An Ent To An Array
*/
function arrayAdd( arr, ent )
    arr[ table.maxn( arr ) + 1 ] = ent
    return arr
end

/*
Removes Any Nil Entries From Array
*/
function arrayRemoveUndefined( arr )
    local newArr = { } 
    local index = 0
    
	for index = 1, table.maxn( arr ) do
		if( arr[ index ] == nil ) then
			// Continue 
	    else
	        newArr[ table.maxn( newArr ) + 1 ] = arr[ index ]
	    end
	end

	return newArr
end

/*
Randomizes Array And Returns New One
*/
function arrayRandomize( arr )
    local index = nil
    local temp = nil
    local x = nil
    
    for index = 1, table.maxn( arr ) do
        x = Shared.GetRandomInt( 1, table.maxn( arr ) )
        temp = arr[ index ]
        arr[ index ] = arr[ x ]
        arr[ x ] = temp
    end
    
    return arr
end

/*
Reverses Array And Returns New One
*/
function arrayReverse( arr )
    local index = nil
    local arr2 = { }
    
    for index = table.maxn( arr ) - 1, index >= 0, index - 1 do
		arr2[ table.maxn( arr2 ) ] = arr[ index ]
	end
	
	return arr2
end

/*
Returns If Ent Is In Array
*/
function isInArray( arr, ent )
    local index = nil
    
    for index = 1, table.maxn( arr ) do
        if( arr[ index ] == ent ) then
            return true
        end
	end
	
	return false
end

/*
Merges Two Arrays And Returns New One (No Dupes)
*/
function arrayMerge( arr, arr2 )
    local match = false
    local index = nil
    local index2 = nil
    local arr3 = { }

	if ( table.maxn( arr1 ) == 0 ) then
		return arr2
	end
	if ( table.maxn( arr2 ) == 0 ) then
		return arr
	end
	
	arr3 = arr
	
	for index = 1, table.maxn( arr2 ) do
		match = false
		
		for index = 1, table.maxn( arr ) do
			if( arr1[ index2 ] == arr2[ index ] ) then
				match = true
				break
			end
		end
		
		if( match ) then
			// Nothing
		else
			arr3[ table.maxn( arr3 ) ] = arr2[ index ]
		end
	end
	
	return arr3
end

/*
Hide Entity
*/
function hide()
    self.isVisible = false
    self.SetIsVisible( false )
end

/*
Show Entity
*/
function show()
    self.isVisible = true
    self.SetIsVisible( true )
end

/****************************************************************************
    Flags
        A Boolean Method Of Checking Variables On Entities.
        Default On Initialization Is False.
****************************************************************************/

function flag( flag )
    if( self.flag[ flag ] == nil ) then
        Print( "%s", "Tried to check a flag that wasn't init: " + flag )
    end

    return self.flag[ flag ]
end

function flagInit( flag )
    if( self.flag == nil ) then
        self.flag = { }
    end
    
    self.flag[ flag ] = false
end

function flagSet( flag )
    if( self.flag[ flag ] == nil ) then
        Print( "%s", "Tried to set a flag that wasn't init: " + flag )
    end
    
    self.flag[ flag ] = true
end

function flagClear( flag )
    if( self.flag[ flag ] == nil ) then
        Print( "%s", "Tried to clear a flag that wasn't init: " + flag )
    end
    
    self.flag[ flag ] = false
end

/****************************************************************************
    AI House Keeping
****************************************************************************/

function SetAILimit( num )
    Game.instance.SetAILimit( num )
end

function GetAILimit( num )
    return Game.instance.GetAILimit()
end

function setHealth( health )
    self.old_health = self.health
    self.health = health
end

function resetHealth()
    if( self.old_health ~= nil and self.old_health > 0 ) then
        self.health = self.old_health
    end
end

function setAccuracy( accuracy )
    if( self.old_accuracy ~= nil ) then
        self.old_accuracy = self.base_accuracy
    end
    
    sellf.base_accuracy = accuracy
end

function resetAccuracy()
    if( self.old_accuracy ~= nil ) then
        self.base_accuracy = self.old_accuracy
    end

    self.old_accuracy = nil
end

/****************************************************************************
    Math
****************************************************************************/

function coinToss()
    return Shared.GetRandomInt( 100 ) >= 50
end

function vectorMultiply( vec, num )
    local vec = Vector( vec.x * num, vec.y * num, vec.z * num )
    return vec
end

function randomVector( num )
    local vec = Vector( Shared.GetRandomFloat( 0, num ) - num * 0.5, Shared.GetRandomFloat( 0, num ) - num * 0.5, Shared.GetRandomFloat( 0, num ) - num * 0.5 )
    return vec
end

function flatAngle( ang )
    local newAng = Vector( 0, ang.y, 0 )
	return newAng
end

function flatOrigin( org )
    local newOrg = Vector( org.x, org.y, 0 )
	return newOrg
end

/****************************************************************************
    Debug
****************************************************************************/

function PrintLn( msg )
    Shared.Message( msg )
end

function waitForever()
    while ( true ) do
        // Loop For Eternity
    end
end

function assert( value )
    if( not value ) then
        return false
    end
    
    return true
end

function assertEx( value, msg )
    if( not value ) then
        Shared.Message( msg )
        return false
    end
    
    return true
end

function assertMsg( msg )
    Shared.Message( msg )
end